import { useState, useRef, MouseEvent } from 'react'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog'
import { VisuallyHidden } from '@radix-ui/react-visually-hidden'
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'

interface CustomDialogProps {
  // 触发器
  trigger?: React.ReactNode
  // 标题
  title?: string
  // 描述
  description?: string
  // 内容
  children?: React.ReactNode
  // 组件传参
  fnChildren?: (
    closeDialog: () => void,
    handleControl?: (open: boolean) => void,
  ) => React.ReactNode
  // 是否模态
  modal?: boolean
  // 是否显示
  open?: boolean
  // 关闭回调
  onOpenChange?: (open: boolean) => void
  // 取消按钮文本
  cancelText?: string
  // 确认按钮文本
  confirmText?: string
  // 取消回调
  onCancel?: () => void
  // 确认回调
  onConfirm?: () => void
  // 是否显示页脚
  showFooter?: boolean
  className?: string
  // 宽度
  width?: string
  // 拖拽移动
  move?: boolean
}

export const CustomDialog = ({
  trigger,
  title,
  description,
  children,
  fnChildren,
  modal = true,
  open: controlledOpen,
  onOpenChange,
  cancelText = 'Cancel',
  confirmText = 'Confirm',
  onCancel,
  onConfirm,
  showFooter = false,
  width = '',
  className,
  move = false,
}: CustomDialogProps) => {
  const [internalOpen, setInternalOpen] = useState(false)
  const isControlled = controlledOpen !== undefined
  const open = isControlled ? controlledOpen : internalOpen

  const dialogRef = useRef<HTMLDivElement>(null)
  const isDragging = useRef(false)
  const initialMousePos = useRef({ x: 0, y: 0 })
  const currentTransform = useRef({ x: 0, y: 0 })

  const handleOpenChange = (open: boolean) => {
    if (!isControlled) {
      setInternalOpen(open)
    }
    onOpenChange?.(open)
    if (!open) {
      currentTransform.current = { x: 0, y: 0 }
      if (dialogRef.current) {
        dialogRef.current.style.transform = 'translate(-50%, -50%)'
      }
    }
  }

  const handleCancel = () => {
    onCancel?.()
    handleOpenChange(false)
  }

  const handleConfirm = () => {
    onConfirm?.()
    handleOpenChange(false)
  }

  const addMouseUpListener = useRef(() => {
    const handleMouseMove = (e: MouseEvent) => {
      if (!isDragging.current || !dialogRef.current) return

      const newX = e.clientX - initialMousePos.current.x
      const newY = e.clientY - initialMousePos.current.y

      dialogRef.current.style.transform = `translate(calc(-50% + ${newX}px), calc(-50% + ${newY}px))`
      currentTransform.current = { x: newX, y: newY }
    }

    const handleMouseUp = () => {
      if (!isDragging.current || !dialogRef.current) return

      isDragging.current = false

      // 恢复样式
      document.body.style.cursor = 'auto'
      dialogRef.current.style.cursor = 'auto'
      dialogRef.current.style.transition = 'transform 0.2s ease'

      // 移除事件监听
      document.removeEventListener('mousemove', handleMouseMove as any)
      document.removeEventListener('mouseup', handleMouseUp)
    }

    // 添加事件监听
    document.addEventListener('mousemove', handleMouseMove as any)
    document.addEventListener('mouseup', handleMouseUp)
  })

  const handleMouseDown = (e: MouseEvent) => {
    if (!move || !dialogRef.current) return
    e.preventDefault()

    isDragging.current = true
    initialMousePos.current = {
      x: e.clientX - currentTransform.current.x,
      y: e.clientY - currentTransform.current.y,
    }

    // 设置样式
    document.body.style.cursor = 'move'
    dialogRef.current.style.cursor = 'move'
    dialogRef.current.style.transition = 'none'
    addMouseUpListener.current()
  }

  return (
    <Dialog open={open} modal={modal} onOpenChange={handleOpenChange}>
      {trigger && <DialogTrigger asChild>{trigger}</DialogTrigger>}
      <DialogContent ref={dialogRef} className={cn(className, width)}>
        {title || description ? (
          <DialogHeader
            className={move ? 'cursor-move select-none' : ''}
            onMouseDown={handleMouseDown}
          >
            {title ? (
              <DialogTitle>{title}</DialogTitle>
            ) : (
              <VisuallyHidden>
                <DialogTitle>Hidden Title</DialogTitle>
              </VisuallyHidden>
            )}
            {description && <DialogDescription>{description}</DialogDescription>}
          </DialogHeader>
        ) : (
          <>
            <VisuallyHidden>
              <DialogTitle>Hidden Title</DialogTitle>
            </VisuallyHidden>
            <div className="h-0 w-full"></div>
          </>
        )}
        {fnChildren ? fnChildren(handleCancel, handleOpenChange) : null}
        {children}
        {showFooter && (
          <DialogFooter className="gap-2">
            <Button variant="outline" onClick={handleCancel}>
              {cancelText}
            </Button>
            <Button onClick={handleConfirm}>{confirmText}</Button>
          </DialogFooter>
        )}
      </DialogContent>
    </Dialog>
  )
}

// 用法示例
/*
export const DialogDemo = () => {
  const [open, setOpen] = React.useState(false)

  return (
    <CustomDialog
      trigger={<Button>打开对话框</Button>}
      title="编辑资料"
      description="修改你的个人信息"
      open={open}
      onOpenChange={setOpen}
      onConfirm={() => {
        console.log('confirmed')
      }}
    >
      <div className="py-4">这里是对话框的内容</div>
    </CustomDialog>
  )
}

// 受控模式
const [open, setOpen] = useState(false);

return (
  <CustomDialog
    trigger={<Button>打开</Button>}
    title="标题"
    description="描述文本"
    open={open}
    onOpenChange={setOpen}
    onConfirm={() => {
      // 处理确认逻辑
    }}
  >
    <div>对话框内容</div>
  </CustomDialog>
);

// 简单模式
return (
  <CustomDialog
    trigger={<Button>打开</Button>}
    title="标题"
  >
    <div>对话框内容</div>
  </CustomDialog>
);

// 无页脚模式
return (
  <CustomDialog
    trigger={<Button>打开</Button>}
    title="标题"
    showFooter={false}
  >
    <div>对话框内容</div>
  </CustomDialog>
);
*/
